LAST_DDL_TIME vs TIMESTAMP nas views DBA/ALL/USER_OBJECTS. Tem diferença?

Por Eduardo Legatti,
Postado en julho 2013

Não é raro muita gente confundir essas duas colunas existentes nas views de dicionário de dados DBA/ALL/USER_OBJECTS. Afinal, qual é a diferença entre elas? Quando é que a informação de data e horário de uma é atualizada e da outra não? Pois bem, vamos então a alguns exemplos práticos de forma a demonstrar essa diferença.


 C:\>sqlplus scott/tiger  
  SQL*Plus: Release 10.2.0.1.0 - Production on Seg Mai 2 11:49:38 2011  
  Copyright (c) 1982, 2005, Oracle.  All rights reserved.  
  Conectado a: 
  Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
  With the Partitioning, OLAP and Data Mining options  
  SQL> desc user_objects  
  Nome                          Nulo?    Tipo 
  ----------------------------- -------- ---------------------------- 
  OBJECT_NAME                            VARCHAR2(128) 
  SUBOBJECT_NAME                         VARCHAR2(30)
  OBJECT_ID                              NUMBER  
  DATA_OBJECT_ID                         NUMBER  
  OBJECT_TYPE                            VARCHAR2(19) 
  CREATED                                DATE  
  LAST_DDL_TIME                          DATE  
  TIMESTAMP                              VARCHAR2(19)
  STATUS                                 VARCHAR2(7)  
  TEMPORARY                              VARCHAR2(1) 
  GENERATED                              VARCHAR2(1) 
  SECONDARY                              VARCHAR2(1)   
  
 

Primeiramente, podemos perceber que LAST_DDL_TIME é uma coluna do tipo DATE e TIMESTAMP, por incrível que pareça, é um VARCHAR2(19). Irei criar abaixo uma tabela de exemplo e realizar algumas operações nela.


SQL> create table t1 (id number); 
   Tabela criada.  
   SQL> select object_name,created,last_ddl_time,timestamp  
   2    from user_objects   
   3   where object_name='T1';  
   OBJECT_NAME     CREATED             LAST_DDL_TIME       TIMESTAMP 
   --------------- ------------------- ------------------- ------------------- 
   T1              02/05/2011 11:59:00 02/05/2011 11:59:00 2011-05-02:11:59:00   
   
 

Acima, podemos perceber que tanto a coluna CREATED, como LAST_DDL_TIME e TIMESTAMP possuem a mesma informação de data e horário. O que acontece se modificarmos a estrutura da tabela?


SQL> alter table t1 modify id number(10,2);   
 Tabela alterada. 
 SQL> select object_name,created,last_ddl_time,timestamp   
 2    from user_objects   
 3   where object_name='T1';  
 OBJECT_NAME     CREATED             LAST_DDL_TIME       TIMESTAMP 
 --------------- ------------------- ------------------- ------------------- 
 T1              02/05/2011 11:59:00 02/05/2011 12:00:00 2011-05-02:12:00:00    
 
 

Ambas as colunas LAST_DDL_TIME e TIMESTAMP tiveram suas informações atualizadas. Mas, o que acontece agora se eu simplesmente conceder alguns privilégios (SELECT, por exemplo) para algum outro usuário?


SQL> grant select on t1 to adam;  
  Concessão bem-sucedida. 
  SQL> select object_name,created,last_ddl_time,timestamp  
  2    from user_objects   
  3   where object_name='T1';  
  OBJECT_NAME     CREATED             LAST_DDL_TIME       TIMESTAMP 
  --------------- ------------------- ------------------- -------------------  
  T1              02/05/2011 11:59:00 02/05/2011 12:02:00 2011-05-02:12:00:00    
      

Podemos perceber que somente a coluna LAST_DDL_TIME teve sua informação atualizada, apesar do comando GRANT ser um comando DCL (Data Control Language). No mais, podemos perceber abaixo que o comando REVOKE terá o mesmo efeito apenas na coluna LAST_DDL_TIME.


SQL> revoke select on t1 from adam; 
   Revogação bem-sucedida.  
   SQL> select object_name,created,last_ddl_time,timestamp  
   2    from user_objects  
   3   where object_name='T1';  
   OBJECT_NAME     CREATED             LAST_DDL_TIME       TIMESTAMP
   --------------- ------------------- ------------------- ------------------- 
   T1              02/05/2011 11:59:00 02/05/2011 12:04:00 2011-05-02:12:00:00    
      

Existem mais comandos que afetam apenas a coluna LAST_DDL_TIME e não a coluna TIMESTAMP? Sim.


SQL> alter table t1 move; 
   Tabela alterada.   
   SQL> select object_name,created,last_ddl_time,timestamp  
   2    from user_objects  
   3   where object_name='T1'; 
   OBJECT_NAME     CREATED             LAST_DDL_TIME       TIMESTAMP 
   --------------- ------------------- ------------------- ------------------- 
   T1              02/05/2011 11:59:00 02/05/2011 12:06:00 2011-05-02:12:00:00   
   SQL> insert into t1 values (1);  
   1 linha criada. 
   SQL> commit;  
   Commit concluído.  
   SQL> truncate table t1;  
   Tabela truncada.  
   SQL> select object_name,created,last_ddl_time,timestamp 
   2    from user_objects  
   3   where object_name='T1';  
   OBJECT_NAME     CREATED             LAST_DDL_TIME       TIMESTAMP
   --------------- ------------------- ------------------- ------------------- 
   T1              02/05/2011 11:59:00 02/05/2011 12:08:00 2011-05-02:12:00:00   

      

Perceberam que o comando ALTER TABLE MOVE... e TRUNCATE TABLE... atualizaram apenas a coluna LAST_DDL_TIME? Irei agora realizar o mesmo teste só que agora com uma FUNCTION. (obs: Poderia também ser uma STORED PROCEDURE ou uma TRIGGER).


SQL> create or replace function data_atual return date is  
  2   data date;  
  3  begin   
  4     select sysdate into data from dual;   
  5     return data;  
  6  end;  
  7  /   
  Função criada.  
  SQL> select object_name,created,last_ddl_time,timestamp 
  2    from user_objects   
  3   where object_name='DATA_ATUAL';   
  OBJECT_NAME     CREATED             LAST_DDL_TIME       TIMESTAMP 
  --------------- ------------------- ------------------- ------------------- 
  DATA_ATUAL      02/05/2011 12:59:00 02/05/2011 12:59:00 2011-05-02:12:59:00 
  
      

Acima, podemos perceber que tanto a coluna CREATED, como LAST_DDL_TIME e TIMESTAMP possuem a mesma informação de data e horário. O que acontece se modificarmos o código PL/SQL da função?


SQL> create or replace function data_atual return date is   
 2   data date;   
 3  begin    
 4     select sysdate+1 into data from dual;  
 5     return data;   
 6  end;    
 7  /    
 Função criada.    
 SQL> select object_name,created,last_ddl_time,timestamp 
 2    from user_objects   
 3   where object_name='DATA_ATUAL';  
 OBJECT_NAME     CREATED             LAST_DDL_TIME       TIMESTAMP 
 --------------- ------------------- ------------------- ------------------- 
 DATA_ATUAL      02/05/2011 12:59:00 02/05/2011 13:00:00 2011-05-02:13:00:00  
 
      

Ambas as colunas LAST_DDL_TIME e TIMESTAMP tiveram suas informações atualizadas. Mas, o que acontece se eu simplesmente conceder alguns privilégios (EXECUTE, por exemplo) para algum outro usuário?


SQL> grant execute on data_atual to adam;  
  Concessão bem-sucedida. 
  SQL> select object_name,created,last_ddl_time,timestamp  
  2    from user_objects    
  3   where object_name='DATA_ATUAL';  
  OBJECT_NAME     CREATED             LAST_DDL_TIME       TIMESTAMP 
  --------------- ------------------- ------------------- ------------------- 
  DATA_ATUAL      02/05/2011 12:59:00 02/05/2011 13:02:00 2011-05-02:13:00:00   
      

Podemos perceber que somente a coluna LAST_DDL_TIME teve sua informação atualizada. Vale a penas salientar que o comando REVOKE terá o mesmo efeito. O que acontece agora se apenas compilarmos a função sem qualquer alteração em seu código fonte?


SQL> alter function data_atual compile; 
   Função alterada.   
   SQL> select object_name,created,last_ddl_time,timestamp   
   2    from user_objects   
   3   where object_name='DATA_ATUAL';  
   OBJECT_NAME     CREATED             LAST_DDL_TIME       TIMESTAMP 
   --------------- ------------------- ------------------- ------------------- 
   DATA_ATUAL      02/05/2011 12:59:00 02/05/2011 13:04:00 2011-05-02:13:00:00 
   
      

Novamente podemos perceber que somente a coluna LAST_DDL_TIME teve sua informação atualizada.

A coluna LAST_DDL_TIME armazena a informação de data e horário sobre a última vez quando o objeto foi modificado por uma instrução DDL, incluindo alguns comandos que envolvam modificações no nível de extensões (extents) do segmento. Vale a pena salientar que essa modificação também vale para comandos DCL como (GRANT e REVOKE) que foram lançados sobre o objeto. Isso também vale para os objetos PL/SQL como functions, stored procedures, triggers, entre outros, incluindo-se o comando COMPILE executado sobre o mesmo.

Por fim, a coluna TIMESTAMP armazena a informação de data e horário sobre a última vez quando o objeto foi modificado, excluindo-se qualquer operação DCL (GRANT, REVOKE) e excluindo-se também alguns comandos DDL que afetem o objeto no nível de extensões (extents) do segmento. No caso de objetos PL/SQL, exclui-se também o comando COMPILE.

Portanto, se quiser saber realmente quando houve alguma modificação estrutural na tabela ou alguma modificação no código de um de objeto PL/SQL, confie na coluna TIMESTAMP.

Eduardo Legatti é Analista de Sistemas e DBA Oracle. É pós graduado em Gerência da Tecnologia da Informação, possui as certificações OCA 9i - OCP 9i/10g/11g – OCE, e vem trabalhando como DBA Oracle desde a versão 8.0.5. Freqüentemente posta artigos em http://eduardolegatti.blogspot.com